import json
import os
from PyQt5.QtWidgets import QWidget,QGridLayout, QGroupBox, QHeaderView, QHBoxLayout, QVBoxLayout, QLabel, QStyledItemDelegate, QDesktopWidget, QPushButton, QFileDialog, QComboBox, QFrame, QScrollArea, QAbstractItemView, QTableWidgetItem, QTableWidget, QSpacerItem, QSizePolicy
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QObject, QEvent
from PyQt5.QtGui import QPainter, QPen, QColor, QDoubleValidator, QPixmap
from pydantic import BaseModel, Field, field_validator
import gui.controls.envs as envs
import pandas as pd
# import gui.controls.envs as envs
from ..dlg_mulit_instance import DlgMutliInstance
from ..custom_table import CustomTable
from ..dlg_params import DlgParams
from ..util.file_operation import FileOperation
from ..custom_widget import LineEditFloat, LineEditStr, LineEditInt, SelectBox


from enum import Enum



class FloatValidatorDelegate(QStyledItemDelegate):
    def __init__(self, parent=None):
        super(FloatValidatorDelegate, self).__init__(parent)
        self.validator = QDoubleValidator(self)

    def createEditor(self, parent, option, index):
        editor = super(FloatValidatorDelegate, self).createEditor(parent, option, index)
        editor.setValidator(self.validator)
        return editor


# 定义 Pydantic 模型
class LifeAnalysisModel(BaseModel):
    damageCount: int = Field(
        description="形状参数",
        alias="shapeParameter",
        required=False,
    )
    damageCenterX: float = Field(
        description="试件系数",
        alias="specimenCoefficient",
        required=False,
    )
    damageCenterY: float = Field(
        description="置信系数",
        alias="confidenceCoefficient",
        required=False,
    )
    honeycombCoreHeight: float = Field(
        description="可靠性系数",
        alias="reliabilityCoefficient",
        required=False,
    )
    damageExcisionDiameter: str = Field(
        description="寿命统计结果",
        alias="lifeAnalysisResults",
        required=False,
    )


class DlgLifeAnalysis(DlgMutliInstance):
    lifeAnalysis_save_signal = pyqtSignal(object)
    def __init__(self, parent=None):
        super(DlgLifeAnalysis, self).__init__(parent)
        
        self.setWindowTitle('寿命分析')
        self.resize(400,300)
        layout = QVBoxLayout()

        groupBox = QGroupBox("")
        contentLayout = QHBoxLayout()
        groupBox.setLayout(contentLayout)
        self.widgetDict = {}
        self.gridLayout = QGridLayout()
        self.modelToGridLayout(LifeAnalysisModel, self.gridLayout)

        statisticsLayout = QVBoxLayout()
        btnLayout = QHBoxLayout()
        importBtn = QPushButton("导入")
        importBtn.clicked.connect(self.on_importBtn_clicked)
        btnLayout.addWidget(importBtn)
        btnLayout.addStretch()
        logoLab1 = QLabel(self)
        logoLab1.setPixmap(QPixmap("icons/add.png").scaled(15, 15, Qt.KeepAspectRatio))  # 替换为你的图片路径
        logoLab1.setAlignment(Qt.AlignCenter)
        logoLab1.mousePressEvent = self.addStatistics
        logoLab2 = QLabel(self)
        logoLab2.setPixmap(QPixmap("icons/del.png").scaled(15, 15, Qt.KeepAspectRatio))  # 替换为你的图片路径
        logoLab2.setAlignment(Qt.AlignCenter)
        logoLab2.mousePressEvent = self.delStatistics
        btnLayout.addWidget(logoLab1)
        btnLayout.addWidget(logoLab2)
        statisticsLayout.addLayout(btnLayout)
        self.widgetDict['statisticsTable'] = CustomTable(rows=0, columns=1, useCustomMenu=False)
        self.widgetDict['statisticsTable'].setHorizontalHeaderLabels(["寿命值"])
        self.widgetDict['statisticsTable'].rowSetFloat([0])
        statisticsLayout.addWidget(self.widgetDict['statisticsTable'])

        contentLayout.addLayout(self.gridLayout)
        contentLayout.addItem(QSpacerItem(10, 20, QSizePolicy.Minimum, QSizePolicy.Expanding))
        contentLayout.addLayout(statisticsLayout)
        contentLayout.setStretchFactor(self.gridLayout, 5)
        contentLayout.setStretchFactor(statisticsLayout, 3)

        btnLayout = QHBoxLayout()
        btnLayout.setAlignment(Qt.AlignCenter)  # 设置居中对齐
        pBtnOK = QPushButton("保存")
        pBtnOK.setObjectName("pBtnOK")
        pBtnOK.clicked.connect(self.on_pBtnOK_clicked)
        pBtnCancel = QPushButton("取消")
        pBtnCancel.setObjectName("pBtnCancel")
        pBtnCancel.clicked.connect(self.close)
        btnLayout.addWidget(pBtnOK)
        btnLayout.addWidget(pBtnCancel)

        layout.addWidget(groupBox)
        layout.addLayout(btnLayout)
        self.setLayout(layout)

        self.cacheFile = "data/ipimas/uis/lifeAnalysis.json"
        self.loadData()
        
    def modelToGridLayout(self, model, gridLayout):
        fileds = model.model_fields
        for row, (field_name, field_info) in enumerate(fileds.items()):
            label = QLabel(field_info.description)
            gridLayout.addWidget(label, 2*row, 0)
            if issubclass(field_info.annotation, Enum):
                self.widgetDict[field_name] = SelectBox(options=[{"title":item.alias, "value":item.alias} for item in list(field_info.annotation)])
                self.widgetDict[field_name].setMinimumWidth(100)
            else:
                field_type = field_info.annotation
                if field_type is float :
                    widget = LineEditFloat()
                elif field_type is int :
                    widget = LineEditInt()
                else:
                    widget = LineEditStr()
                widget.setPlaceholderText(f"请输入{field_info.description}")
                self.widgetDict[field_name] = widget
            gridLayout.addWidget(self.widgetDict[field_name], 2*row, 1)
            if row != 0:
                spacer = QSpacerItem(20, 100, QSizePolicy.Minimum, QSizePolicy.Expanding)
                gridLayout.addItem(spacer, 2*row-1, 0, 1)  # 在第1行添加一个占位符，占据第0列和第1列
    

    def addStatistics(self, event):
        self.widgetDict['statisticsTable'].add()

    def delStatistics(self, event):
        self.widgetDict['statisticsTable'].delete()
    
    def on_importBtn_clicked(self):
        file_dialog = QFileDialog()
        file_dialog.setNameFilter("EXCEL files (*.xlsx *.xls)")
        # 设置对话框标题
        file_dialog.setWindowTitle("选择excel文件")
        # 显示对话框并获取用户选择的文件
        if file_dialog.exec_():
            # 用户点击了“打开”或“保存”，获取选中的文件路径
            file_path = file_dialog.selectedFiles()[0]
            self.load_excel(file_path)
            
    def load_excel(self, filePath):
        try:
            data = []
            excelData = pd.read_excel(filePath, header=0, usecols=["寿命值"])
            for index, row in excelData.iterrows():
                data.append([
                    row["寿命值"],
                ])
            self.widgetDict['statisticsTable'].addMulitRows(data)
        except FileNotFoundError:
            print(f"Error: 文件 '{filePath}' 未找到.")

    def loadData(self):
        data = FileOperation.read_json(self.cacheFile)
        if data is None:
            return
        for key, value in data.items():
            if isinstance(self.widgetDict[key], CustomTable):
                self.widgetDict[key].addMulitRows(value)
            else:
                self.widgetDict[key].setValue(value)
    
    def on_pBtnOK_clicked(self):
        data = {}
        for key, widget in self.widgetDict.items():
            if isinstance(widget, CustomTable):
                data[key] = widget.getTableData()
            else:
                data[key] = widget.getValue()
                
        FileOperation.write_json(self.cacheFile, data)
        # if hasattr(envs, 'ipimas_updateMaterialSetting'):
        #     envs.ipimas_updateMaterialSetting(type="参数化建模")
        self.close()
        self.lifeAnalysis_save_signal.emit(data)
    
    
        
def toFloat(value):
    try:
        return float(value)
    except ValueError:
        return None